﻿// Lesson25_5.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>

#include <future>
#include <thread>

void DoWork(std::promise<int> thePromise)
{
	int sum = 0;
	for (size_t i = 0; i < 1000; i++)
	{
		sum += i;
	}
	thePromise.set_value(sum);
	////...
	//thePromise.set_exception(std::make_exception_ptr(0));
}

int CalcSumFrom0(int steps)
{
	int sum = 0;
	for (size_t i = 0; i < steps; i++)
	{
		sum += i;
	}
	return sum;
}

int ExceptFunction()
{
	throw std::runtime_error("a test exception");
}

//void DoWork(int& thePromise)
//{
//	int sum = 0;
//	for (size_t i = 0; i < 1000; i++)
//	{
//		sum += i;
//	}
//	thePromise=(sum);
//
//}

//template<typename T,typename F,typename A1,typename A2>
//std::future<T> MyAsync(F f, A1 arg1, A2 Arg2)
//{
//	std::packaged_task<int(int)> task(f);
//	auto theFuture = task.get_future();
//
//	std::thread t{ std::move(task),arg1,arg2 };
//
//	return theFuture;
//}

int main()
{
	//int res = 0;
	//std::thread t{ DoWork,std::ref(res) };
	//t.join();

	//std::cout << "sum of from 0 to 1000=" << res;

	//std::promise<int> thePromise;
	//auto theFuture = thePromise.get_future();
	//std::thread t{ DoWork, std::move(thePromise) };
	//int res = theFuture.get();
	//
	//std::cout << "sum of from 0 to 1000=" << res;
	//t.join();

	//std::packaged_task<int(int)> task(CalcSumFrom0);
	//auto theFuture = task.get_future();

	//std::thread t{ std::move(task),1000 };

	//std::cout<<theFuture.get()<<std::endl;

	//t.join();

	//auto theFuture = std::async(std::launch::async,CalcSumFrom0, 1000);
	//std::cout << theFuture.get() << std::endl;

	//auto exfuture = std::async(std::launch::async, ExceptFunction);

	//try
	//{
	//	int res = exfuture.get();
	//	std::cout << "res=" << res << std::endl;
	//}
	//catch (const std::exception& ex)
	//{
	//	std::cout << ex.what()<<std::endl;
	//}

	std::promise<void> t1Started, t2Started;

	std::promise<int> sigPromise;

	std::shared_future<int> sigFuture = sigPromise.get_future().share();

	auto result1 = std::async(std::launch::async, 
	[sigFuture, &t1Started] {
		t1Started.set_value();
		int param = sigFuture.get();
		std::cout << "t1=" << param << std::endl;
	});

	auto result2 = std::async(std::launch::async,
		[sigFuture, &t2Started] {
		t2Started.set_value();
		int param = sigFuture.get();
		std::cout << "t2=" << param << std::endl;
	});

	t1Started.get_future().wait();
	t2Started.get_future().wait();

	sigPromise.set_value(30);

	return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门提示: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
